# 控制器提示弹窗组件增加自定义按钮功能

# 背景

控制器中的提示弹窗是直接使用的Ext.MessageBox,查看源码发现其中的按钮是写死的,在第一次创建弹窗时根据配置去初始化按钮,且配置是闭包在函数里,外部无法修改到,为了实现设计效果,这里做统一的修改,增加自定义按钮功能。

# 实现

这里需要重写Ext.MessageBox

# 获取弹窗

由于Ext.MessageBox的弹窗使用了单例模式,只能在调用原函数获取弹窗后动态添加按钮

getDialog: function(titleText){
    win = origGetDialog.apply(this, arguments);
    // 添加自定义按钮
    if (opt.customButtons) {
        opt.customButtons.forEach(function(b) {
            var button = new Ext.Button({
                text: b.text,
                handler: function () {
                    if(win.isVisible()){
                        win.hide();
                        Ext.callback(opt.fn, opt.scope||window, [b.key], 1);
                        opt = null;
                    }
                },
                isCustomButton: true
            });
            addButtons.push(button);
            win.fbar.addItem(button);
        })
    }
    win.fbar.doLayout();
    win.on("hide", this.handleHide);
    return win;
},

# 隐藏弹窗

弹窗隐藏时,需要将自定义按钮都销毁,不能影响下一次的显示。

handleHide: function () {
    // 移除自定义按钮
    addButtons.forEach(function (button) {
        win.fbar.remove(button);
    });
    addButtons = [];
    win = null;
},

# 显示弹窗

调用Ext.MessageBox的show方法后,由于我们自定义的按钮不在Ext.MessageBox的初始化按钮中,所以会被隐藏,这里我们手动将自定义的按钮给显示出来,并校正弹窗宽度。

show: function(options){
    opt = options;
    var _this = origShow.call(this, options);
    // 自定义的按钮
    if (opt.customButtons) {
        var width = 0;
        // 显示
        win.fbar.items.items.forEach(function (button) {
            if (button.isCustomButton) {
                button.show();
            }
            if (!button.hidden) {
                width += button.getEl().getWidth() + 15;
            }
        });
        // 修正宽度
        var oldWidth = win.getWidth();
        if (width > oldWidth) {
            win.setWidth(width);
        }
    }
    
    return _this;
},

# 使用

提示弹窗通常有两种调用方法:

  • mgr中调用
  • 直接函数调用

下面来一一实现

# mgr中

mgr中可配置type : "confirm",即可实现弹窗效果。

这里新增customButtons配置项,配置后按钮即可显示。

需要注意的是按钮的key需要配yes或no,对应mgr中封装好的success和failure回调。

"changeExtendCard.confirm.reboot" : {
    type : "confirm",
    getMsg : function (act, mgr) {
        var str = _('替换扩展卡需重启交换机才能生效。'),
            info = _('重启交换机可能导致下接设备暂时进入离线或待修复状态。');
        
        if (mgr.handlerExtendCardType === 'add') {
            str = _('新增扩展卡需重启交换机才能生效。');
        }
        
        return String.format('<div>{0}</div><div style="color: #888;line-height: 20px;">{1}</div>', str, info);
    },
    customButtons: [
        {
            text: _('稍后重启'),
            key: 'no'
        },
        {
            text: _('立即重启'),
            key: 'yes'
        }
    ],
    success : "reboot.request",
    failure: "std.showerr"
},

# 函数调用

之前已经封装了SF.confirm,同样在之中增加customButtons配置项,callback中返回配置的key

需要注意的是,之前SF.confirm的配置是一个一个传入的,这里做了优化,可直接传一个配置对象进去。

SF.confirm({
	msg: '1',
	customButtons: [
		{
			text: '111',
			key: 'a'
		},
		{
			text: '222',
			key: 'b'
		}
	],
	callback: function (btn) {
		console.log(btn)
	}
})

# 参数

新增参数customButtons,配置如下

参数 类型 含义
text string 按钮显示文字
key string 按钮回调中回传做判断的键值